
public class NeuralLayer {

    public int numberOfNeurons;
    public Neuron neuronsArray[];
    public double inputArray[];
    public double netInput;
    public int activation;

    public NeuralLayer(int numberOfNeurons, int numberOfInputsPerNeuron, int activation) {
        this.numberOfNeurons = numberOfNeurons;
        this.neuronsArray = new Neuron[numberOfNeurons];
        this.inputArray = new double[numberOfInputsPerNeuron];

        for (int i = 0; i < numberOfNeurons; i++) {
            this.neuronsArray[i] = new Neuron(numberOfInputsPerNeuron);
        }
        
        this.activation = activation;
    }
    public NeuralLayer(int numberOfNeurons, int numberOfInputsPerNeuron) {
       this(numberOfNeurons, numberOfInputsPerNeuron, 0);
    }
    public void FeedForward() {
        for (int i = 0; i < neuronsArray.length; i++) {
            netInput = 0;

            for (int j = 0; j < neuronsArray[i].weightArray.length; j++) {
                netInput = netInput + inputArray[j] * neuronsArray[i].weightArray[j];
            }

            
            if (activation == 0) { //Estamos haciendo la derivada del sigmoide
                neuronsArray[i].output = sigmoid(netInput);            
                neuronsArray[i].outputDerived = neuronsArray[i].output*(1-neuronsArray[i].output);
            
            }else if (activation == 1) { //estamos haciendo la derivada del tanh
                neuronsArray[i].output = tanh(netInput);            
                neuronsArray[i].outputDerived = 1 - Math.pow(neuronsArray[i].output,2);
            } 
            else if (activation == 2){ //funcion lineal
                neuronsArray[i].output = (netInput);            
                neuronsArray[i].outputDerived = 1 ;          
            }else if (activation == 3){ //funcion cuadrado
                neuronsArray[i].output = Math.pow(netInput,2);            
                neuronsArray[i].outputDerived = 2*neuronsArray[i].output ;          
            }else {
                //sigmoide por defecto
                neuronsArray[i].output = sigmoid(netInput);            
                neuronsArray[i].outputDerived = neuronsArray[i].output*(1-neuronsArray[i].output);           
            }

        }
    }

    //Me da el output de la capa en un array
    public double[] outputArray() {

        double result[] = new double[neuronsArray.length];

        for (int i = 0; i < neuronsArray.length; i++) {
            result[i] = neuronsArray[i].output;

        }

        return result;
    }
    
    public double activationFunction(double netInput) {
        if (activation == 0) {
            return sigmoid(netInput);
        }
        else if (activation == 1) {
            return tanh(netInput);
        } else {
            return 0;
        }
    }

    private double sigmoid(double netInput) {
        return 1 / (1 + Math.exp(-netInput));
    }
    
    private double tanh(double netInput) {
        //double a = Math.exp( netInput );
        //double b = Math.exp( -netInput );
        //return ((a-b)/(a+b));        
        return  (Math.exp(netInput*2.0)-1.0)/(Math.exp(netInput*2.0)+1.0);
    }

}
